package com.delicaterock.mpw;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class SimpleDBHelper extends SQLiteOpenHelper {

    private static final int DATABASE_VERSION = 1;
    public static final String DATABASE_NAME = "mpw";
    public static final String TABLE_NAME = "wallet";
    public static final String FNAME = "name";
    public static final String FAPP = "application";
    public static final String FUSR = "user";
    public static final String FPWD = "password";
    public static final String FOPT = "option";
    public static final String FIP = "ip";
    public static final String FPORT = "port";
    public static final String FTIMESTAMP = "timestamp";
    public static String password = "";
    
    private static final String WALLET_TABLE_CREATE = String.format("CREATE TABLE IF NOT EXISTS %s (_id INTEGER primary key autoincrement, %s TEXT, %s TEXT, %s TEXT, %s TEXT, %s TEXT, %s TEXT, %s TEXT, %s TEXT DEFAULT CURRENT_TIMESTAMP)",
    		TABLE_NAME, FNAME, FAPP, FUSR, FPWD, FOPT, FIP, FPORT, FTIMESTAMP);
	
	private Context mContext;
	
    SimpleDBHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        mContext = context;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(WALLET_TABLE_CREATE);
    }

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

	}
	
	public Cursor getWalletCursor(SQLiteDatabase db) {
		Cursor record = db.query(TABLE_NAME, new String[]{"_id", FNAME, FAPP, FUSR, FPWD, FOPT, FIP, FPORT, FTIMESTAMP}, null, null, null, null, FNAME+" ASC");
		return record;
	}
	
	public void deleteWalletByID(SQLiteDatabase db, String id) {
		db.delete(TABLE_NAME, "_id=?", new String[]{id});
	}
	
	public Cursor queryWalletByID(SQLiteDatabase db, String id) {		
		Cursor record = db.query(TABLE_NAME, new String[]{FNAME, FAPP, FUSR, FPWD, FOPT, FIP, FPORT, FTIMESTAMP}, "_id=?", new String[]{id}, null, null, FTIMESTAMP+" DESC");
		return record;
	}

	public Cursor queryWalletByApp(SQLiteDatabase db, String app) {		
		Cursor record = db.query(TABLE_NAME, new String[]{FNAME, FAPP, FUSR, FPWD, FOPT, FIP, FPORT, FTIMESTAMP}, FAPP+"=?", new String[]{app}, null, null, FTIMESTAMP+" DESC");
		return record;
	}
	
	private String encrypt(String cleartext) {
		if (password.length()>0) {
			try {
				return SimpleCrypto.encrypt(password, cleartext);
			} catch (Exception e) {
				return "";
			}
		} else {
			return cleartext;
		}
	}
	
	public static String decrypt(String crypto) {
		if (password.length()>0) {
			try {
				return SimpleCrypto.decrypt(password, crypto);
			} catch (Exception e) {
				return crypto;
			}
		} else {
			return crypto;
		}
	}

	public void saveConnectionByName(String name, String app, String usr,
			String pwd, String opt, String ip, String port) {
    	ContentValues values = new ContentValues();
    	values.put(FNAME, name);
    	values.put(FAPP, app);
    	try {
			values.put(FUSR, encrypt(usr));
	    	values.put(FPWD, encrypt(pwd));			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	values.put(FOPT, opt);
    	values.put(FIP, ip);
    	values.put(FPORT, port);
    	Date now = new Date();
    	values.put(FTIMESTAMP, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(now));
    	SQLiteDatabase db = this.getWritableDatabase();

    	if (db.update(TABLE_NAME, values, FNAME+"=?", new String[]{name})<1) {
        	if (db.replace(TABLE_NAME, null, values)<0);    		
    	};

    	db.close();
    	Log.i("SimpleDBHelper:saveConnectionByName():", name);
	}
	
	private static void printList(String title, List list) {
		Log.d("printList "+title," total:"+list.size());
		for (int i=0; i<list.size(); i++) {
			Log.d("#"+i, list.get(i).toString());
		}
	}
	
	public static ArrayList<String> sortIPs(String[] iplist) {
		ArrayList<String> rtn = new ArrayList<String>();		
		if (iplist==null || iplist.length==0) {
			return rtn;
		}
		
		ArrayList<String> list = new ArrayList<String>(Arrays.asList(iplist));
		printList("original", list);
		String prefixClassC = getLocalIP();
		prefixClassC = prefixClassC.substring(0, prefixClassC.lastIndexOf("."));
		String prefixClassB = prefixClassC.substring(0, prefixClassC.lastIndexOf("."));
		String prefixClassA = prefixClassB.substring(0, prefixClassB.lastIndexOf("."));
		Log.d("prefixes:", prefixClassC+" "+prefixClassB+" "+prefixClassA);
		
		for (int i=0; i<list.size(); i++) {
			Log.d("ip:", prefixClassC+" "+list.get(i));
			if (list.get(i).startsWith(prefixClassC)) {
				rtn.add(list.get(i));
				list.remove(i);
				break;
			}
		}
		for (int i=0; i<list.size(); i++) {
			if (list.get(i).startsWith(prefixClassB)) {
				rtn.add(list.get(i));
				list.remove(i);
				break;
			}
		}
		for (int i=0; i<list.size(); i++) {
			if (list.get(i).startsWith(prefixClassA)) {
				rtn.add(list.get(i));
				list.remove(i);
				break;
			}
		}
		
		// add the rest of ips
		rtn.addAll(list);
		printList("sorted", rtn);
		return rtn;
	}
	
	public static String getLocalIP() {
		// get local ip
		String localIP = "127.0.0.1";
		try {
			Enumeration<NetworkInterface> theIntfList = NetworkInterface.getNetworkInterfaces();
			Enumeration<InetAddress> theAddrList = null;
			NetworkInterface theIntf = null;
			InetAddress theAddr = null;
			while(theIntfList.hasMoreElements())
			{
				theIntf = theIntfList.nextElement();
				theAddrList = theIntf.getInetAddresses();
				while(theAddrList.hasMoreElements()) {
					InetAddress curIP = theAddrList.nextElement();
					if (curIP instanceof Inet4Address && !curIP.isLoopbackAddress()) {
						localIP = curIP.getHostAddress();
						Log.d("local IP internal:", localIP);
					}
				}
			}		  
		} catch (Exception e) {
			e.printStackTrace();
		}
		Log.d("local IP:", localIP);
		return localIP;
	}
}
